import wx
import wx.lib.flatnotebook as FNB
import TreeBookPanel
from modules import meide as ui
from modules import Object

class TabPanel(wx.Panel):
    def __init__(self, parent, obj):
        wx.Panel.__init__(self, parent)
        self.obj = obj
        self.pages = {}
        self.value_set = []
        
        self.box = box = ui.VBox()
        self.tabbook = FNB.FlatNotebook(self, agwStyle=FNB.FNB_VC8 | FNB.FNB_NO_X_BUTTON | FNB.FNB_HIDE_ON_SINGLE_TAB)
        
        self.CreatePages(self.tabbook)
        
        box.add(self.tabbook, proportion = 1, flag = wx.EXPAND | wx.ALL)
        
        self.AddPages(self.tabbook)
        ui.create(self, box, 0)
        
    def CreatePages(self, book):
        if hasattr(self.obj, '_styles'):
            ls = []
            for v in self.obj._styles.values():
                ls.append((v['order'], v))
            ls.sort()
            for order,v in ls:
                if v['parent']:
                    pagename = v['parent']
                else:
                    pagename = tr('General')
                    
                page = self.CreatePage(pagename)
                self.AddItem(page, v)
                    
    def CreatePage(self, pagename):
        if not pagename in self.pages:
            page = wx.ScrolledWindow(self.tabbook)
            page.EnableScrolling(False, True)
            page.SetScrollbars(10, 10, 30, 30)
            self.pages[pagename] = page
            page.box = ui.SimpleGrid().create(page).auto_layout()
            self.value_set.append(page.box)
        else:
            page = self.pages[pagename]
        return page
    
    def AddItem(self, page, v):
        if not v['label']:
            label = v['name']
            v['label'] = label
        else:
            label = v['label']
            
        value = getattr(self.obj, v['name'])
        obj = None
            
        if not v.has_key('control'):
            pass
        else:
            kind = v['control']
            if not isinstance(kind, str):
                obj = kind
                if hasattr(obj, 'SetParent'):
                    obj.SetParent(page)
            else:
                if kind == 'text':
                    obj = ui.Text(value, style = v.has_key('style') and v['style'] or 0)
                elif kind == 'check':
                    label = ''
                    obj = ui.Check(value, label = v['label'])
                elif kind in ('num', 'int'):
                    obj = ui.Int(value)
                elif kind == 'hexint':
                    obj = ui.HexInt(value)
                elif kind == 'choice':
                    obj = ui.SingleChoice(value, choices = v['choices'])
                elif kind == 'password':
                    obj = ui.Password(value)
                elif kind == 'openfile':
                    obj = ui.OpenFile(value)
                elif kind == 'opendir':
                    obj = ui.Dir(value)
                    
        if v.has_key('span'):
            span = v['span']
        else:
            span = label and False or True
        if obj:
            page.box.add(label, obj, name = v['name'], span=span)
    
    def AddPages(self, book):
        for key, page in self.pages.items():
            self.tabbook.AddPage(page, key)
            
    def GetValues(self):
        v = {}
        for box in self.value_set:
            v.update(box.GetValue())
        return v
    
    def UpdateObject(self):
        vals = self.GetValues()
        for name, val in vals.items():
            setattr(self.obj, name, val)
        if hasattr(self.obj, 'ToUpdate'):
            self.obj.ToUpdate()
        
class TabDialog(wx.Dialog):
    def __init__(self, parent, obj, size=(850, 500), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER):
        wx.Dialog.__init__(self, parent, -1, title=tr("Property"), size=size, style=style)
        self.obj = obj
        
        self.box = box = ui.VBox(namebinding='widget')
        self.panel = TabPanel(self, obj)
        box.add(self.panel, proportion = 1, flag = wx.EXPAND | wx.ALL)
        
        box.add(wx.StaticLine(self), flag = wx.EXPAND | wx.ALL)
        
        buttons = [(tr('OK'), wx.ID_OK, 'btnOk'), 
            (tr('Cancel'), wx.ID_CANCEL, 'btnCancel'),
            (tr('Apply'), wx.ID_APPLY, 'btnApply')]
        box.add(ui.simple_buttons(buttons), flag=wx.ALIGN_CENTER|wx.BOTTOM)
        box.bind('btnOk', 'click', self.OnOk)
        box.bind('btnApply', 'click', self.OnApply)
        
        self.box.create(self).auto_layout()
        
    def OnOk(self, event):
        self.OnApply(event)
        event.Skip()
        
    def OnApply(self, event):
        self.panel.UpdateObject()
        if hasattr(self.obj, 'Save'):
            self.obj.Save()

class TreePanel(wx.Panel):
    def __init__(self, parent, obj):
        wx.Panel.__init__(self, parent)
        self.obj = obj
        self.pages = {}
        self.value_set = []
        
        self.box = box = ui.VBox()
        self.treebook = TreeBookPanel.TreeBookPanel(self, -1)
        
        self.CreatePages(self.treebook)
        
        box.add(self.treebook, proportion = 1, flag = wx.EXPAND | wx.ALL)
        
        self.AddPages(self.treebook)
        ui.create(self, box, 0)
        
    def CreatePages(self, treebook):
        if hasattr(self.obj, '_styles'):
            for k, v in self.obj._styles.items():
                if v['parent']:
                    pagename = v['parent']
                else:
                    pagename = tr('General')
                    
                n = []
                for p in pagename.split('/'):
                    n.append(tr(p))
                    page = self.CreatePage('/'.join(n))
                
                self.AddItem(page, v)
            
    def AddItem(self, page, v):
        if not v['label']:
            label = v['name']
            v['label'] = label
        else:
            label = v['label']
            
        value = getattr(self.obj, v['name'])
            
        if not v.has_key('control'):
            pass
        else:
            kind = v['control']
            if not isinstance(kind, str):
                obj = kind
                if hasattr(obj, 'SetParent'):
                    obj.SetParent(page)
            else:
                if kind == 'text':
                    obj = ui.Text(value, style = v.has_key('style') and v['style'] or 0)
                elif kind == 'check':
                    label = ''
                    obj = ui.Check(value, label = v['label'])
                elif kind in ('num', 'int'):
                    obj = ui.Int(value)
                elif kind == 'choice':
                    obj = ui.SingleChoice(value, choices = v['choices'])
                elif kind == 'password':
                    obj = ui.Password(value)
                elif kind == 'openfile':
                    obj = ui.OpenFile(value)
                elif kind == 'opendir':
                    obj = ui.Dir(value)
                    
        if v.has_key('span'):
            span = v['span']
        else:
            span = label and False or True
        page.box.add(label, obj, name = v['name'], span=span)
                
    def CreatePage(self, pagename):
        if pagename not in self.pages:
            page = wx.ScrolledWindow(self.treebook)
            page.EnableScrolling(False, True)
            page.SetScrollbars(10, 10, 30, 30)
            self.pages[pagename] = page
            page.box = ui.SimpleGrid().create(page).auto_layout()
            self.value_set.append(page.box)
        else:
            page = self.pages[pagename]
        return page
        
    def AddPages(self, treebook):
        if len(self.pages) > 0:
            temp = {}
            for key, page in self.pages.items():
                if temp.has_key(key):
                    continue
                n = []
                for item in key.split('/'):
                    n.append(tr(item))
                    name = '/'.join(n)
                    if not temp.has_key(name):
                        parentname = '/'.join(n[0:len(n)-1])
                        parent = temp.has_key(parentname) and temp[parentname] or None
                        child = self.treebook.add_page(self.pages[name], n[len(n)-1], parent)
                        temp[name] = child
                        
    def GetValues(self):
        v = {}
        for box in self.value_set:
            v.update(box.GetValue())
        return v
    
    def UpdateObject(self):
        vals = self.GetValues()
        for name, val in vals.items():
            setattr(self.obj, name, val)
        self.obj.ToUpdate()

class TreeDialog(wx.Dialog):
    
    def __init__(self, parent, obj, size=(850, 500), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER):
        wx.Dialog.__init__(self, parent, -1, title=tr("Property"), size=size, style=style)
        self.obj = obj
        
        self.box = box = ui.VBox(namebinding='widget')
        self.panel = TreePanel(self, obj)
        box.add(self.panel, proportion = 1, flag = wx.EXPAND | wx.ALL)
        
        box.add(wx.StaticLine(self), flag = wx.EXPAND | wx.ALL)
        
        buttons = [(tr('OK'), wx.ID_OK, 'btnOk'), 
            (tr('Cancel'), wx.ID_CANCEL, 'btnCancel'),
            (tr('Apply'), wx.ID_APPLY, 'btnApply')]
        box.add(ui.simple_buttons(buttons), flag=wx.ALIGN_CENTER|wx.BOTTOM)
        box.bind('btnOk', 'click', self.OnOk)
        box.bind('btnApply', 'click', self.OnApply)
        
        self.box.create(self).auto_layout()
        
    def OnOk(self, event):
        self.OnApply(event)
        event.Skip()
        
    def OnApply(self, event):
        self.panel.UpdateObject()
        if hasattr(self.obj, 'Save'):
            self.obj.Save()
   
MOP_TAB_PAGE = 0x0001
MOP_TREE_PAGE = 0x0002
         
class MultiObjectPanel(wx.Panel):
    def __init__(self, parent, mopStyle = 0x0001):
        wx.Panel.__init__(self, parent)
        self.objs = {}
        self.pages = {}
        self.value_set = {}
        self.bookstyle = mopStyle
        self.tabpage = []
        
        self.box = box = ui.VBox()
        self.treebook = TreeBookPanel.TreeBookPanel(self, -1)
        
        box.add(self.treebook, proportion = 1, flag = wx.EXPAND | wx.ALL)
        ui.create(self, box, 0)
        
    def AddObject(self, pagename, obj):
        self.objs[pagename] = obj
        self.value_set[obj] = []
        
    def UpdatePages(self):
        self.CreatePages()
        self.AddPages()
    
    def CreatePages(self):
        for pagename, obj in self.objs.items():
            n = []
            for i in pagename.split('/'):
                n.append(tr(i))
                self.CreatePage('/'.join(n))
        
    def CreatePage(self, pagename):
        if not pagename in self.pages:
            if not pagename in self.objs:
                page = wx.Panel(self.treebook)
                self.pages[pagename] = page
            else:
                if self.bookstyle == 0x0001:
                    page = TabPanel(self.treebook, self.objs[pagename])
                    self.tabpage.append(page)
                    self.pages[pagename] = page
                else:
                    self.CreateObjectTree(pagename, self.objs[pagename])
                
    def CreateObjectTree(self, pagename, obj):
        if hasattr(obj, '_styles'):
            for k, v in obj._styles.items():
                if v['parent']:
                    pn = v['parent']
                else:
                    pn = tr('General')
                    
                pn = pagename + '/' + pn
                n = []
                for i in pn.split('/'):
                    n.append(tr(i))
                    page = self.CreateObjectTreePage('/'.join(n), obj)
                self.AddObjectTreeItem(page, obj, v)
        else:
            page = wx.Panel(self.treebook)
            self.pages[pagename] = page
            
    def CreateObjectTreePage(self, pagename, obj):
        if not pagename in self.pages:
            page = wx.ScrolledWindow(self.treebook)
            page.EnableScrolling(False, True)
            page.SetScrollbars(10, 10, 30, 30)
            self.pages[pagename] = page
            page.box = ui.SimpleGrid().create(page).auto_layout()
            self.value_set[obj].append(page.box)
        else:
            page = self.pages[pagename]
        return page
    
    def AddObjectTreeItem(self, page, object, v):
        if not v['label']:
            label = v['name']
            v['label'] = label
        else:
            label = v['label']
            
        value = getattr(object, v['name'])
            
        if not v.has_key('control'):
            pass
        else:
            kind = v['control']
            if not isinstance(kind, str):
                obj = kind
                if hasattr(obj, 'SetParent'):
                    obj.SetParent(page)
            else:
                if kind == 'text':
                    obj = ui.Text(value, style = v.has_key('style') and v['style'] or 0)
                elif kind == 'check':
                    label = ''
                    obj = ui.Check(value, label = v['label'])
                elif kind in ('num', 'int'):
                    obj = ui.Int(value)
                elif kind == 'choice':
                    obj = ui.SingleChoice(value, choices = v['choices'])
                elif kind == 'password':
                    obj = ui.Password(value)
                elif kind == 'openfile':
                    obj = ui.OpenFile(value)
                elif kind == 'opendir':
                    obj = ui.Dir(value)
                    
        if v.has_key('span'):
            span = v['span']
        else:
            span = label and False or True
        page.box.add(label, obj, name = v['name'], span=span)
    
    def AddPages(self):
        if len(self.pages) > 0:
            temp = {}
            for key, page in self.pages.items():
                if temp.has_key(key):
                    continue
                n = []
                for item in key.split('/'):
                    n.append(tr(item))
                    name = '/'.join(n)
                    if not temp.has_key(name):
                        parentname = '/'.join(n[0:len(n)-1])
                        parent = temp.has_key(parentname) and temp[parentname] or None
                        child = self.treebook.add_page(self.pages[name], n[len(n)-1], parent)
                        temp[name] = child
                        
    def GetObjectTreeValues(self, obj):
        v = {}
        l = self.value_set[obj]
        for box in l:
            v.update(box.GetValue())
        return v
    
    def UpdateObject(self):
        if self.bookstyle == 0x0001:
            for page in self.tabpage:
                page.UpdateObject()
        else:
            for k, obj in self.objs.items():
                vals = self.GetObjectTreeValues(obj)
                for name, val in vals.items():
                    setattr(obj, name, val)
                    obj.ToUpdate()
                    
class MultiObjectDialog(wx.Dialog):
    
    def __init__(self, parent, bookstyle = 0x0001, size=(850, 500), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER):
        wx.Dialog.__init__(self, parent, -1, title=tr("Property"), size=size, style=style)
        
        self.box = box = ui.VBox(namebinding='widget')
        self.panel = MultiObjectPanel(self, bookstyle)
        box.add(self.panel, proportion = 1, flag = wx.EXPAND | wx.ALL)
        
        box.add(wx.StaticLine(self), flag = wx.EXPAND | wx.ALL)
        
        buttons = [(tr('OK'), wx.ID_OK, 'btnOk'), 
            (tr('Cancel'), wx.ID_CANCEL, 'btnCancel'),
            (tr('Apply'), wx.ID_APPLY, 'btnApply')]
        box.add(ui.simple_buttons(buttons), flag=wx.ALIGN_CENTER|wx.BOTTOM)
        box.bind('btnOk', 'click', self.OnOk)
        box.bind('btnApply', 'click', self.OnApply)
        
        self.box.create(self).auto_layout()
        
    def AddObject(self, pagename, obj):
        self.panel.AddObject(pagename, obj)
        
    def UpdatePages(self):
        self.panel.UpdatePages()
        
    def OnOk(self, event):
        self.OnApply(event)
        event.Skip()
        
    def OnApply(self, event):
        self.panel.UpdateObject()